Skip to content

Conversation

KurtE
Copy link
Contributor

@KurtE KurtE commented Sep 30, 2025

Start of support for the is31fl3197 LED controller used by Arduino in the Arduino Giga Display shield.

So far there is just enough implemented that allows me to control the LEDS, to the same extent as our version of the library we implemented that runs on ArduinoCore-zephyr

@pillo79 @facchinm - I am not sure what direction Arduino is heading with functionality such as this.
Add support to zephyr? Or do it external as libraries within ArduinoCore-zephyr (either integrated within the zephyr builds or external libraries), This is also true, about for some of the other
features of the display, like the display itself. Should there be samples setup to actually
display something on the display, preferably without the need for LVGL.

So far this only has the minimal support for setting up to 4 LEDS (the GIGA only uses 3).

Added sample sketch that runs on the GIGA. Currently it works with just
west build -p -b arduino_giga_r1//m7

I put the device tree into sample/boards. Potentially it should be defined as part of the
overlay in the arduino_giga_display_shield, in which case the west build should
define the shield as part of the command.

Let me know know what you think.
Thanks

@KurtE KurtE force-pushed the giga_shield_leds branch 6 times, most recently from fd309e3 to b69ff55 Compare October 1, 2025 12:30
@KurtE
Copy link
Contributor Author

KurtE commented Oct 1, 2025

@pillo79 @facchinm and all - As far as I can tell, the basic parts of this PR are working. That is I can set the RGB led on the
giga display, the same as we have setup in the Arduino library. I know that this it currently does not fully implement all
of the features of this LED chip driver, but if this is pulled in, others can add it, especially if there are boards that use some of
the different features.

I am going to mark this as ready to review, however I know there are issues with twister, as it appears like the GIGA board
and guessing probably likewise the Portenta H7 have not been used as a setup for any of the samples. One issue I ran into
was the GIGA was not marked in the yaml file as supporting I2C, which I have added and the twister run goes a lot farther

Currently I have the sample setup to work with just specifying board as arduino_giga_r1//m7, as the shield currently
does not define the LED info. I don't know if one can specify an overlay file for a shield under a samples
boards directory, like maybe set the name as arduino_giga_display_shield.overlay? I may try it again with build line like:
west build -p -b arduino_giga_r1//m7 --shield arduino_giga_display_shield
I believe this can also be made to work with a portenta H7 with the mid carrier board. As I believe it's connector
to for the display shield includes an I2C object connected to those pins. May try that out of curiosity.
But I don't believe any of the Arduino Portenta carrier boards or shields are defined as shields in zephyr.
EDIT: - Portenta connector does not have I2C connections to the Display shield. So that won't work.
(Unless you use jumpers, which I have tried from I2C0 pins on Mid Carrier to the SCL/SDA pins on the
camera connector)

Also should mention: that the code is hard coded similarly to the is31fl3194 code in that it assumes RED/GREEN/BLUE
as the LEDS and it assumes they are on OUT1-3. I have the start of OUT4, that I again hard coded to WHITE:
But suppose I use one of these drivers for a stop light and the leds are: Green, Yellow, Red. Also should the colors
and slots be dictated by the colors passed in. For example if I have only two colors can I specify that I am using Out 2 and 3?

But before I go much further, it would help to know if this is a direction that Arduino wishes to go.

Copy link
Contributor

@simonguinot simonguinot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @KurtE,

Thanks for this PR !

Can it be merged with the driver is31fl3194 ? into a is31fl319x driver ?

I didn't check but I am asking because in Linux the leds-is31fl319x driver supports the IS31FL319{0,1,3,6,9} models...

@KurtE
Copy link
Contributor Author

KurtE commented Oct 1, 2025

Can it be merged with the driver is31fl3194 ? into a is31fl319x driver ?

I didn't check but I am asking because in Linux the leds-is31fl319x driver supports the IS31FL319{0,1,3,6,9} models...

Good question, both of them have stuff in common, and I started off that way, but then found many of the registers
appear to be different. Like fixed max current here versus set. Also can control which channels are active or not,
maybe you can with the 94 as well. They probably can be combined, but unclear how much they would share in
common.

@pillo79 As the one who originally did the 94 version, What do you think?

@pillo79
Copy link
Contributor

pillo79 commented Oct 2, 2025

Thanks Kurt! I also think this is worth merging with the existing driver, there's a lot of common code, and the few exceptions look like they can be specifically handled. Take a look at the end of drivers/led/lp50xx.c, for example, in how it defines id and max_leds depending on one of the many HW models. If you need many of these, you can also store id directly or a clever enum index into a register table, etc.

Oh, and re/ Arduino attitude, upstream is the way to go so 👍 on that! By all means make it part of the Giga Display shield, that way it will be automatically available everywhere you use that and not only in the test code 🙂

@mjs513
Copy link

mjs513 commented Oct 2, 2025

@KurtE
Had to pretty much do the same thing for trying to merge the OV7675 into the OV7670 driver. Heres the link I used as a base to the LED driver:

zephyr/drivers/led/lp50xx.c

Lines 391 to 413 in 8843fd9

#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_lp5009
DT_INST_FOREACH_STATUS_OKAY_VARGS(LP50XX_DEVICE, 5009, LP5012_NUM_MODULES)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_lp5012
DT_INST_FOREACH_STATUS_OKAY_VARGS(LP50XX_DEVICE, 5012, LP5012_NUM_MODULES)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_lp5018
DT_INST_FOREACH_STATUS_OKAY_VARGS(LP50XX_DEVICE, 5018, LP5024_NUM_MODULES)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_lp5024
DT_INST_FOREACH_STATUS_OKAY_VARGS(LP50XX_DEVICE, 5024, LP5024_NUM_MODULES)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_lp5030
DT_INST_FOREACH_STATUS_OKAY_VARGS(LP50XX_DEVICE, 5030, LP5036_NUM_MODULES)
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT ti_lp5036
DT_INST_FOREACH_STATUS_OKAY_VARGS(LP50XX_DEVICE, 5036, LP5036_NUM_MODULES)

@KurtE
Copy link
Contributor Author

KurtE commented Oct 2, 2025

Thanks @pillo79 @mjs513,

Thanks Kurt! I also think this is worth merging with the existing driver

Can do. At least the basics, that the display shield uses. Don't have any other things to try more advanced stuff on.

My first thoughts were to hack it and drive everything off of Product ID. I believe the 94 has a fixed ID of 0xce
Whereas the 97s ID is the I2C 8 bit address: Currently checked like:
if (prod_id != (config->bus.addr << 1)) {

Oh, and re/ Arduino attitude, upstream is the way to go so 👍 on that! By all means make it part of the Giga Display shield, that way it will be automatically available everywhere you use that and not only in the test code 🙂

I agree, that in the Zephyr world, having it all here under the shield is the way to go and not have to put the DT info in the
test sketch. I had it there to begin with, with the testing, will move it back there.

Some questions on this, should I then remove the GIGA from the integration section of the sample.yaml? As I don't believe
there are any other examples for them?

Include Portenta H7? I have a overlay I experimented with yesterday, that had the LEDS working on an H7 plugged into a MID
Carrier, which has a display shield plugged into it. But it only worked if I put jumpers to I2C pins. I tried it as the Display Shield
schematic that looked like there was a connection for Portenta with I2C pins... Just not sure how.
Guessing probably punt for now.

Main Secondary Question:

Currently with ArduinoCore-zephyr if I wish to build for a GIGA, it includes all of the Giga Shield stuff, regardless if I actually have a shield.

With the MBED version, only the basics for the display are included with a board release in the library Arduino_H7_video, The
rest of the functionality is contained in libraries you need to install.

I decided to try first with the LEDS as it is pretty self contained and not very large. Our zephyr version of Arduino library for this:

#include "GigaDisplayRGB.h"

GigaDisplayRGB::GigaDisplayRGB(){
}

void GigaDisplayRGB::begin()
{
    Wire1.begin();
    writeByte(0x1, 0xF1);
    writeByte(0x2, 0xFF);
}

void GigaDisplayRGB::on(uint8_t r, uint8_t g, uint8_t b)
{
    writeByte(0x10, r);
    writeByte(0x11, g);
    writeByte(0x12, b);
    writeByte(0x2b, 0xc5);
}

void GigaDisplayRGB::off()
{
    on(0, 0, 0);
}

void GigaDisplayRGB::writeByte(uint8_t subAddress, uint8_t data)
{
    Wire1.beginTransmission(0x50);
    Wire1.write(subAddress);
    Wire1.write(data);
    Wire1.endTransmission();
}

Longer term question: how much of the stuff in the ArduinoCore-zephyr overlays/config files maybe should be
migrated upstream, but that is beyond this scope.

@KurtE
Copy link
Contributor Author

KurtE commented Oct 2, 2025

Quick question:

Current driver is pretty hard coded to RED/GREEN/BLUE and if I read it correctly it is assumed that the user
always has to pass in 3 colors in that order, but the output code may change the order of them as maybe the
channels to the hardware are not wired that way?

Now with the 97 it can handle up to 4 channels, I started off hard coding the 4th channel to WHITE for maybe
RGBW type LEDS.

But the LED Header file defines other colors as well:

#define LED_COLOR_ID_WHITE      0
#define LED_COLOR_ID_RED        1
#define LED_COLOR_ID_GREEN      2
#define LED_COLOR_ID_BLUE       3
#define LED_COLOR_ID_AMBER      4
#define LED_COLOR_ID_VIOLET     5
#define LED_COLOR_ID_YELLOW     6
#define LED_COLOR_ID_IR         7
#define LED_COLOR_ID_MAX        8

There feels like there should be way to specify different colors? And maybe mappings?
Ok to ignore for now?

Also is there any reason things are hard coded to have to set all of the LEDS each time? That is should it be
allowed to only set the Green LED, by passing in index 1, count 1?
That is can there be a few different pieces of code that maybe change a state of one LED. Sort of along the line that
GIGA has similar like LED (minus driver)
image
And each of the three colors are often driven by different places in the code base.

Thanks

@KurtE
Copy link
Contributor Author

KurtE commented Oct 2, 2025

Sorry, another quick question: Is there any Boards other than the Nicla Sense ME that uses is31fl3194?
(I don't have one of those to test that I did not break it)

@KurtE KurtE force-pushed the giga_shield_leds branch from fc1363c to 70fea85 Compare October 5, 2025 00:16
@KurtE
Copy link
Contributor Author

KurtE commented Oct 5, 2025

@pillo79 @mjs513 @simonguinot - I split this up into multiple commits.
I also redid the color mapping... i.e. there is none.

I have the GIGA display shield working with it.
The Example: I updated to look through the channels, to figure out which was the R and G and B,
And then the sample remaps the colors.

@KurtE KurtE force-pushed the giga_shield_leds branch 7 times, most recently from 25ecad4 to 102b7f3 Compare October 5, 2025 16:36
@KurtE KurtE requested review from pillo79 and simonguinot October 5, 2025 18:04
@KurtE
Copy link
Contributor Author

KurtE commented Oct 5, 2025

Please retry analysis of this Pull-Request directly on SonarQube Cloud

how?

Copy link
Contributor

@pillo79 pillo79 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite a better shape, thanks for the effort! 👍

Note that commit ' drivers: led: is31fl319x - redo color to channel ' introduces changes to the sample README.rst that are later removed and then re-added in the following commits. 👀 Ideally, at that stage there should be no mention of other chips yet.

@KurtE KurtE force-pushed the giga_shield_leds branch from 819bc45 to 6df2cd0 Compare October 6, 2025 13:31
@zephyrbot zephyrbot requested a review from pillo79 October 6, 2025 13:33
@KurtE KurtE force-pushed the giga_shield_leds branch 3 times, most recently from b5ee1a4 to f0aae7f Compare October 6, 2025 17:44
KurtE added 3 commits October 6, 2025 10:51
In preparation to allow this driver to support more than
one IS31FL319x object such as ...97, rename the
source file and the functions to make them more
generic.

I  also changed the enumeration/creation of object
to generate the right names for the current 94 objects

Still have not renamed the Kconfig file yet as was having
issues with it not building... Did not load the .c file

Update README.rst

one Kconfig

Delete Kconfig.is31fl3194

Fix documents run
drivers: led: IS31FL3194 to 9x fix redirects,py

Signed-off-by: Kurt Eckhardt <[email protected]>
more refactoring, don't use the 94 registers everywhere.
Introduce structure, with registers and fixed values,
and use it.

Signed-off-by: Kurt Eckhardt <[email protected]>
Removed the driver knowing anything about what
color each channel is.  When you output to
an LED with a buffer it simply writes the
channels out with buffer.

Also removed the assumptions that the leds
are either a) RGB  or b) 3 channels and
instead use them the way they are defined.

That is for example if we have 4 channels, we
could define an LED with just one color in it
and we could define another with three.

The user can define 4 leds each with color yellow.

For each LED it counts how many buffers were used
by previous LEDs and starts there and outputs N
channels.

Decided it looked cleaner to use helper function
write channels, so implemented it and added it
to the call table.

Updated example sketch:
It manually computes which channel maps to red, green and blue and then
uses those indexes to map the table of colors to the right channels.
Signed-off-by: Kurt Eckhardt <[email protected]>

Update main.c

Update main.c
@KurtE KurtE force-pushed the giga_shield_leds branch 2 times, most recently from 82498b8 to 1788b7f Compare October 6, 2025 18:02
KurtE added 2 commits October 6, 2025 11:59
Add the registers and the like to the .c file plus add a Kconf file
plus bindings.

Updated example sketch: to also check for
is31fl3197 boards

Signed-off-by: Kurt Eckhardt <[email protected]>
Added is31fl3197@50 to overlay

Also updated GIGA board yaml file to say that it supports i2c

And updated sample sketch to mention it

Signed-off-by: Kurt Eckhardt <[email protected]>
@KurtE KurtE force-pushed the giga_shield_leds branch from 1788b7f to f4e7c5c Compare October 6, 2025 18:59
Copy link

sonarqubecloud bot commented Oct 6, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants